'use strict';
// node.js 文件操作对象
// const fs = require('fs');
const path = require('path');
// 数据加密
const crypto = require('crypto');
// 故名思意 异步二进制 写入流
// const awaitWriteStream = require('await-stream-ready').write;
// // 管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
// const Pump = require('mz-modules/pump');
const Controller = require('egg').Controller;
class updateController extends Controller {
  /**
     * @api {Post} /api/update 单文件上传
     * @apiGroup 文件上传
     * @apiParam {file} file （必填）
     * @apiParam {INTEGER} type   1商品，2评价, 3轮播图（必填）
     * @apiParamExample 参数模板
     {
      }
     * @apiSuccessExample 成功返回
    {
        "msg": "添加成功",
        "result": {
            "id": 130,
            "path": "http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1600413603112-f121d135f39f03e48da5fe5e8ced5b0a.jpg"
        }
    }
     *
     * @apiErrorExample 错误返回
     * {
     *  "msg":"请选择文件"
     * }
     *
     */
  // 单文件上传
  async imgFileUpload() {
    const { ctx, service } = this;
    try {
      this.md5 = crypto.createHash('md5');
      let stream;

      try {
        stream = await ctx.getFileStream();
      } catch (error) {
        ctx.body = ctx.response.error('请上传文件');
      }
      if (!stream) {
        return;
      }

      // 新建一个文件名
      let userData = ctx.adminInfo || ctx.userInfo;

      /** 生成filename，文件存储目录及格式为 /project_name_用户id/_时间戳_文件名 */
      let filename =
        `/${userData.id}/_${+new Date()}_` +
        this.md5.update(stream.filename).digest('hex') +
        path.extname(stream.filename).toLocaleLowerCase();
      const cosData = await ctx.helper._upload(filename, stream);

      // 保存到数据库 返回上传的信息
      ctx.body = {
        path: cosData,
      };
    } catch (error) {
      console.log(error);
      ctx.body = ctx.response.error(error.message);
    }
  }
  /**
     * @api {Post} /api/updateM 多文件上传
     * @apiGroup 文件上传
     * @apiParam {file} file （必填）
     * @apiParam {INTEGER} type   1商品，2评价, 3轮播图（必填）
     * @apiParamExample 参数模板
     {
      }
     * @apiSuccessExample 成功返回
     {
        "msg": "添加成功",
        "result": [
            {
                "id": 128,
                "path": "http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1600413578576-f121d135f39f03e48da5fe5e8ced5b0a.jpg"
            },
            {
                "id": 129,
                "path": "http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1600413580121-0d6fd1ff1f18dd1af4e296929a251cc4.jpg"
            }
        ]
    }
     *
     * @apiErrorExample 错误返回
     * {
     *  "msg":"请选择文件"
     * }
     *
     */
  // 多文件上传
  async multiple() {
    const { ctx, service } = this;
    const parts = ctx.multipart();
    let part;
    let type = '';
    // parts() 返回 promise 对象
    let cosData = null;
    const files = [];
    while ((part = await parts()) != null) {
      if (part.length) {
        // 这是 busboy 的字段
        type = part[1];
      } else {
        if (!part.filename) {
          // 这时是用户没有选择文件就点击了上传(part 是 file stream，但是 part.filename 为空)
          // 需要做出处理，例如给出错误提示消息
          return;
        }
        // part 是上传的文件流
        // console.log('field: ' + part.fieldname);
        // console.log('filename: ' + part.filename);
        // console.log('encoding: ' + part.encoding);
        // console.log('mime: ' + part.mime);
        // 文件处理，上传到云存储等等
        try {
          const filename =
            new Date().getTime() +
            '-' +
            crypto.createHash('md5').update(part.filename).digest('hex') +
            path.extname(part.filename);
          const cosData = await ctx.helper._upload(filename, part);

          files.push(cosData);
        } catch (err) {
          // 必须将上传的文件流消费掉，要不然浏览器响应会卡死
          await sendToWormhole(part);
          throw err;
        }
      }
    }
    // 保存到数据库 返回上传的信息
    // console.log('files ==>', files);

    ctx.body = files;

    // let flag = true;
    // try {
    //   // autoFields: true 表示除了文件的其它字段
    //   const parts = this.ctx.multipart({ autoFields: true });
    //   const files = [];
    //   let stream;

    //   // 循环获取数据流
    //   while ((stream = await parts()) != null) {
    //     console.log('stream ==>', stream);
    //     if (!stream.filename) {
    //     // 多文件上传时，只能break,不能return
    //       break;
    //     }

    //     // 这是 form-data 的字段
    //     if (!parts.field.type) {
    //       ctx.body = ctx.response.error('请输入type的值');
    //       return;
    //     }
    //     flag = false;
    //     // 文件表单的name
    //     // 上传的目录，注意upload目录要存在，实际项目中以云服务器地址为准，入库要替换地址符号
    //     const filename = new Date().getTime() + '-' + crypto.createHash('md5').update(stream.filename).digest('hex') + path
    //       .extname(stream.filename);
    //     console.log('filename==>', filename);

    //     // 文件生成绝对路径
    //     // 当然这里这样市不行的，因为你还要判断一下是否存在文件路径
    //     const target = path.join(this.config.baseDir, 'app/public/uploads', filename);
    //     // const targetTemp = path.join('/public/uploads', filename);

    //     const writeStream = fs.createWriteStream(target);
    //     await Pump(stream, writeStream);

    //     // files.push(targetTemp);
    //     files.push({
    //       Bucket: 'shops-1251395798', /* Bucket,名称 必须 */
    //       Region: 'ap-nanjing', /* 所属地域 必须 */
    //       Key: filename, /* 文件名必须 */
    //       FilePath: stream, /** 文件对象 */
    //     });
    //   }
    //   console.log('files ==>', files);

    //   // 保存到数据库 返回上传的信息
    //   ctx.body = await service.photo.index(cosData, parts.field.type);
    //   // ctx.body = ctx.response.success({
    //   // // 表单上传的文件
    //   //   files,
    //   //   // 表单的其它数据，注意放到循环后面，否则拿不到对应的字段
    //   //   fields: parts.field,
    //   // });
    // } catch (error) {
    //   ctx.body = ctx.response.error(error.message);
    // }
    // flag && (ctx.body = ctx.response.error('请选择上传文件'));
  }
  /**
       *
       * @api {POST} /api/imgUpload 上传图片、文件（需要token）
       * @apiName 上传图片、文件
       * @apiGroup 文件模块
       * @apiVersion  1.0.0
       *
       *
       * @apiParam  {Object} file 文件列表（form-data格式）   (传文件时调用)
       * @apiParam  {Array} baseArr base64文件数组(base64格式) （传base64格式时调用）
       * 
       *
       * @apiParamExample  {type} Request-Example:
          [
              File,
              File,
              File
          ]
          或者
      {
          "baseArr":[""]
      }
       *
       *
       * @apiSuccessExample {type} Success-Response:
       * {
       *     msg : "成功操作",    
       *     data : {
       *      [                                                                                         //图片地址数组
                  'https://blog-1251395798.cos.ap-guangzhou.myqcloud.com/image/_1629978756129_1.jpeg',        
                  'https://blog-1251395798.cos.ap-guangzhou.myqcloud.com/application/_1629978756404_2.pdf',
                  'https://blog-1251395798.cos.ap-guangzhou.myqcloud.com/image/_1629978756482_3.jpg' 
              ]
        }
       *
       *
       */
  //  // base64
  async imgBaseUpload() {
    const { app, ctx, service } = this;
    if (!ctx.request.files) {
      let file = ctx.request.body;
      let cosRes = new Array();

      for (let i = 0; i < file.baseArr.length; i++) {
        cosRes[i] = await ctx.helper.uploadBase(file.baseArr[i]);
      }
      await ctx.cleanupRequestFiles();

      // console.log(cosRes);
      return ctx.helper.successModule(cosRes);
    } else {
      let userFileList = ctx.request.files;
      let cosRes = new Array();

      /** 将文件列表遍历进行文件上云，由于 forEach 内部是异步，所以用 for 来解决异步问题 */
      for (let i = 0; i < userFileList.length; i++) {
        cosRes[i] = await ctx.helper._upload(userFileList[i]);
      }

      /** 清空临时文件夹 */
      await ctx.cleanupRequestFiles();

      // console.log(cosRes);
      return ctx.helper.successModule(cosRes);
    }
  }
}

module.exports = updateController;
